package cc.eddic.pratice.programmingparadigms.nginxlog.impl;

import cc.eddic.pratice.programmingparadigms.nginxlog.LogItem;
import cc.eddic.pratice.programmingparadigms.nginxlog.LogReport;
import cc.eddic.pratice.programmingparadigms.nginxlog.NginxLogItem;
import cc.eddic.pratice.programmingparadigms.nginxlog.PageViewsAndUniqueVisitors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class NginxLogParserTyqImpl implements LogReport {
    private static final Logger log = LoggerFactory.getLogger(NginxLogParserTyqImpl.class);

    @Override
    public PageViewsAndUniqueVisitors pageViewsAndUniqueVisitors(List<NginxLogItem> items) {
        long PV = items.size();
        if (PV == 0) {
            return new PageViewsAndUniqueVisitors(0, 0);
        }
        long UV = items.stream()
                .map(item -> item.getIp() + item.getUserAgent())
                .distinct()
                .count();
        if (log.isDebugEnabled()) {
            log.debug("PV: {},UV: {}", PV, UV);
        }
        return new PageViewsAndUniqueVisitors(PV, UV);
    }

    @Override
    public Map<Integer, PageViewsAndUniqueVisitors> pageViewsAndUniqueVisitorsByHour(List<NginxLogItem> items) {
        return items.stream()
                .collect(Collectors.groupingBy(this::NginxTimeToInt))
                .entrySet().stream()
                .collect(Collectors.toMap(Map.Entry::getKey, v -> pageViewsAndUniqueVisitors(v.getValue())));
    }

    @Override
    public List<PathModel> pageViewsAndUniqueVisitorsByPath(List<LogItem> items) {
        return items.stream()
                .collect(Collectors.groupingBy(LogItem::getPath))
                .entrySet().stream()
                .map(logItem -> new PathModel(logItem.getKey(), (pageViewsAndUniqueVisitors(convert(logItem.getValue())).getPageViews()), (pageViewsAndUniqueVisitors(convert(logItem.getValue()))).getUniqueVisitors()))
                .sorted(Comparator.comparing(PathModel::getPv).reversed())
                .collect(Collectors.toList());
    }

    //List<LogItem>转List<NginxLogItem>
    public List<NginxLogItem> convert(List<LogItem> logItemList) {
        return logItemList.stream()
                .map(logItem -> new NginxLogItem(logItem.getIp(), logItem.getTime().toString(), " ", String.valueOf(logItem.getStatus()), String.valueOf(logItem.getBytes()), logItem.getReferer(), logItem.getUserAgent()))
                .collect(Collectors.toList());
    }

    //计算出一条NginxItem对应的时间段
    public int NginxTimeToInt(NginxLogItem nginxLogItem) {
        String NginxTime = nginxLogItem.getTime();
        String time = NginxTime.substring(NginxTime.indexOf(':') + 1, NginxTime.indexOf(':') + 3);
        return Integer.parseInt(time);
    }
}
